#!/usr/bin/env node

// automate the release process
// pre-requisites:
// - real release repo is in a remote called "upstream"
// - on the branch "main"
// - repo clean (nothing pending vs. HEAD)
// - 2FA turned on in npm
"use strict";
const { spawn } = require("child_process");
const fs = require("fs").promises;
const path = require("path");

if (process.argv.length < 3) {
  console.error(`usage: ${process.argv[1]} [--dry-run] <VERSION>`);
  process.exit(1);
}
const args = process.argv.slice(2);
let DRY = false;
if (args[0] === "--dry-run") {
  DRY = true;
  args.shift();
}
const VERSION = args[0];

function e(cmd) {
  console.log(`>>> ${cmd} <<<`);

  return new Promise((resolve, reject) => {
    const c = spawn(cmd, {
      shell: true,
      stdio: "inherit"
    });
    c.on("error", reject);
    c.on("close", code => {
      if (code === 0) {
        resolve();
      } else {
        reject(new Error(`${cmd} failed, exit code ${code}`));
      }
    });
  });
}

async function main() {
  const root = path.resolve(__dirname, "..");
  process.chdir(root);

  // check that we're clean
  await e("git diff-index --quiet HEAD");

  // check that we're on main
  await e("[[ `git branch --show-current` == main ]]");

  // update version in package.json
  const pkg = path.join(root, "package.json");
  const ptxt = await fs.readFile(pkg, "utf8");
  const pjson = JSON.parse(ptxt);
  pjson.version = VERSION;
  await fs.writeFile(pkg, JSON.stringify(pjson, null, 2));

  // build
  await e("npm run build");

  // add files
  await e(`git add ${pkg} lib/version.js lib/parser.js docs/js/benchmark-bundle.min.js docs/js/test-bundle.min.js docs/vendor/peggy/peggy.min.js`);

  // check in
  await e(`git commit -m "Update for v${VERSION}"`);

  // check that we're clean
  await e("git diff-index --quiet HEAD");

  if (DRY) {
    console.log("Stopping.  Dry run.  Reverse last commit with `git reset --hard HEAD~1`");
    process.exit(0);
  }

  // tag
  await e(`git tag "v${VERSION}"`);

  // push tag
  await e(`git push upstream main "v${VERSION}"`);

  // publish
  await e("npm publish");

  // go to GitHub Release page
  console.log("Go to https://github.com/peggyjs/peggy/releases/new");
}

main().catch(e => console.error(e.message));
